# like add_library(new ALIAS old) but avoids add_library cannot create ALIAS target "new" because target "old" is imported but not globally visible. on older cmake
# This can be replaced with a direct alias call once our minimum is cmake 3.18
function(dolphin_alias_library new old)
  string(REPLACE "::" "" library_no_namespace ${old})
  if (NOT TARGET _alias_${library_no_namespace})
    add_library(_alias_${library_no_namespace} INTERFACE)
    target_link_libraries(_alias_${library_no_namespace} INTERFACE ${old})
  endif()
  add_library(${new} ALIAS _alias_${library_no_namespace})
endfunction()

# Makes an imported target if it doesn't exist.  Useful for when find scripts from older versions of cmake don't make the targets you need
function(dolphin_make_imported_target_if_missing target lib)
  if(${lib}_FOUND AND NOT TARGET ${target})
    add_library(_${lib} INTERFACE)
    target_link_libraries(_${lib} INTERFACE "${${lib}_LIBRARIES}")
    target_include_directories(_${lib} INTERFACE "${${lib}_INCLUDE_DIRS}")
    add_library(${target} ALIAS _${lib})
  endif()
endfunction()

function(dolphin_optional_system_library out_use_system library)
  string(TOUPPER ${library} upperlib)
  set(USE_SYSTEM_${upperlib} "" CACHE STRING "Use system ${library} instead of bundled.  ON - Always use system and fail if unavailable, OFF - Always use bundled, AUTO - Use system if available, otherwise use bundled, blank - Delegate to USE_SYSTEM_LIBS.  Default is blank.")
  if("${USE_SYSTEM_${upperlib}}" STREQUAL "")
    if(APPROVED_VENDORED_DEPENDENCIES)
      string(TOLOWER ${library} lowerlib)
      if(lowerlib IN_LIST APPROVED_VENDORED_DEPENDENCIES)
        set(${out_use_system} AUTO PARENT_SCOPE)
      else()
        set(${out_use_system} ON PARENT_SCOPE)
      endif()
    else()
      set(${out_use_system} ${USE_SYSTEM_LIBS} PARENT_SCOPE)
    endif()
  else()
    set(${out_use_system} ${USE_SYSTEM_${upperlib}} PARENT_SCOPE)
  endif()
endfunction()

function(dolphin_add_bundled_library library use_system bundled_path)
  if (${use_system} STREQUAL "AUTO")
    message(STATUS "No system ${library} was found.  Using static ${library} from Externals.")
  else()
    message(STATUS "Using static ${library} from Externals")
  endif()
  if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${bundled_path}/CMakeLists.txt")
    message(FATAL_ERROR "No bundled ${library} was found.  Did you forget to checkout submodules?")
  endif()
  add_subdirectory(${bundled_path} EXCLUDE_FROM_ALL)
endfunction()

function(dolphin_find_optional_system_library library bundled_path)
  dolphin_optional_system_library(use_system ${library})
  string(TOUPPER ${library} upperlib)
  if(use_system)
    # Try a list of versions
    # Will be obsoleted if cmake ever fixes https://gitlab.kitware.com/cmake/cmake/-/issues/26477
    if("DOLPHIN_TRY_VERSIONS" IN_LIST ARGN)
      list(FIND ARGN DOLPHIN_TRY_VERSIONS versions_idx)
      list(REMOVE_AT ARGN ${versions_idx})
      # Extract list of version-like elements from ARGN into version_list
      set(version_list)
      while(TRUE)
        list(LENGTH ARGN len)
        if(len EQUAL versions_idx)
          break()
        endif()
        LIST(GET ARGN ${versions_idx} ver)
        if(ver MATCHES "^[0-9]+(\\.[0-9]+)*$")
          list(APPEND version_list "${ver}")
          list(REMOVE_AT ARGN ${versions_idx})
        else()
          break()
        endif()
      endwhile()
      # Quietly check all the listed versions
      foreach(version IN LISTS version_list)
        find_package(${library} ${version} ${ARGN} QUIET)
        if(${library}_FOUND)
          break()
        endif()
      endforeach()
      # If none were found, find_package one version loudly so the user sees
      if(NOT ${library}_FOUND)
        list(GET version_list 0 first_version)
        find_package(${library} ${first_version} ${ARGN})
      endif()
    else()
      find_package(${library} ${ARGN})
    endif()

    # Yay for cmake packages being inconsistent
    if(DEFINED ${library}_FOUND)
      set(prefix ${library})
    else()
      set(prefix ${upperlib})
    endif()
    if((NOT ${prefix}_FOUND) AND (NOT ${use_system} STREQUAL "AUTO"))
      message(FATAL_ERROR "No system ${library} was found.  Please install it or set USE_SYSTEM_${upperlib} to AUTO or OFF.")
    endif()
  endif()
  if(${prefix}_FOUND)
    message(STATUS "Using system ${library}")
    set(${prefix}_TYPE "System" PARENT_SCOPE)
  else()
    dolphin_add_bundled_library(${library} ${use_system} ${bundled_path})
    set(${prefix}_TYPE "Bundled" PARENT_SCOPE)
  endif()
endfunction()

function(dolphin_find_optional_system_library_pkgconfig library search alias bundled_path)
  dolphin_optional_system_library(use_system ${library})
  string(TOUPPER ${library} upperlib)
  if(use_system)
    pkg_search_module(${library} ${search} ${ARGN} IMPORTED_TARGET)
    if((NOT ${library}_FOUND) AND (NOT ${use_system} STREQUAL "AUTO"))
      message(FATAL_ERROR "No system ${library} was found.  Please install it or set USE_SYSTEM_${upperlib} to AUTO or OFF.")
    endif()
  endif()
  if(${library}_FOUND)
    message(STATUS "Using system ${library}")
    dolphin_alias_library(${alias} PkgConfig::${library})
    set(${library}_TYPE "System" PARENT_SCOPE)
  else()
    dolphin_add_bundled_library(${library} ${use_system} ${bundled_path})
    set(${library}_TYPE "Bundled" PARENT_SCOPE)
  endif()
endfunction()
